/*
 * Videoclient.cpp
 *
 *  Created on: 2010-03-28
 *      Author: kamil
 */

#include "mgr/video/Videoclient.h"

using namespace boost::asio;
using namespace std;

log4cxx::LoggerPtr Videoclient::logger(log4cxx::Logger::getLogger("videoclient"));

Videoclient::Videoclient(boost::asio::io_service & io_service) : io_service(io_service), socket(io_service), archiveData(0)
{

}

Videoclient::~Videoclient() {
	socket.close();
}

void Videoclient::connect(std::string  serverIP, int port)
{
	ip::udp::endpoint listenEndpoint(ip::address::from_string("0.0.0.0"), port);
	socket.open(listenEndpoint.protocol());
	socket.set_option(ip::udp::socket::reuse_address(true));
	socket.bind(listenEndpoint);

	socket.set_option(ip::multicast::join_group(ip::address_v4::from_string(serverIP)/*, ip::address_v4::loopback() */));
	prepareRead();
}

void Videoclient::prepareRead(){
	socket.async_receive(boost::asio::buffer(header, header_size),
			boost::bind(&Videoclient::handleHeader, this,
			boost::asio::placeholders::error,
			boost::asio::placeholders::bytes_transferred));
}

bool Videoclient::areNewDataPresent(){
	return archiveData != 0 ? true : false;
}

void Videoclient::consumeVideodata(map<string, Videodata> * vd, double * timeStamp){
	BOOST_ASSERT(archiveData != 0);	//always do check with areNewDataPresent
	LOG4CXX_TRACE(logger, "Consuming videodata..." << *archiveData);
	std::istringstream archive_stream(*archiveData);
	//	boost::archive::text_iarchive archive(archive_stream);

	boost::archive::binary_iarchive archive(archive_stream);

	archive >> *vd;
	archive >> *timeStamp;
	//	cout<<"DATA: "<<vd["red0"].x<<std::endl;


	delete archiveData;
	archiveData = 0;
}


void Videoclient::handleHeader(const boost::system::error_code & error, std::size_t readDataSize){
	static int header_counter = 0;
	if (readDataSize <= 0) {
		prepareRead();
		return;
	}
	std::istringstream is(std::string(header, header_size));
	data_size = 0;
	if (!(is >> std::hex >> data_size)) {
		throw string("VideoClient: Error while getting header");
	}

	data.resize(header_size + data_size);

	header_counter++;

	socket.async_receive(boost::asio::buffer(data, data.size()),
						boost::bind(&Videoclient::handleData, this,
						boost::asio::placeholders::error,
						boost::asio::placeholders::bytes_transferred));
//	io_service.poll();
}
void Videoclient::handleData(const boost::system::error_code & error, std::size_t){
	map<string, Videodata> vd;	//fixme: delete this

	if (archiveData != 0) delete archiveData;
	archiveData = new string(&data[header_size], data.size() - header_size);

	LOG4CXX_TRACE(logger, "Video data packet before serialization: " << archiveData);

//	std::istringstream archive_stream(archive_data);
//	//	boost::archive::text_iarchive archive(archive_stream);
//
//	if (currentBinaryData) delete currentBinaryData;
//	currentBinaryData = new boost::archive::binary_iarchive(archive_stream);
////	boost::archive::binary_iarchive archive(archive_stream);
////
////	archive >> vd;
////	cout<<"DATA: "<<vd["red0"].x<<std::endl;

	prepareRead();
}
